﻿using BCCommon;
using BCCommon.Enums.TMS;
using BCGPSCommon;
using BCMongoEntity.TMS.Fence;
using MongoDB.Driver;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace BCMongoData.TMS.Fence
{
    public class FenceMongoData : IFenceMongoData
    {
        private readonly MongoDBCommand<FenceMongoEntity> mongoDBCommand;
        private readonly GCJ02_WGS84_TransTools gCJ02_WGS84_TransTools = new GCJ02_WGS84_TransTools();

        public FenceMongoData(IMongoDBConfiguration mongoDBConfiguration)
        {
            mongoDBCommand = new MongoDBCommand<FenceMongoEntity>(mongoDBConfiguration, "Fence");
        }


        public FenceMongoEntity AddNew(FenceMongoEntity fenceMongoEntity, GpsMapType gpsMapType)
        {
            List<Map2DCoordinate> CoordinateList = new List<Map2DCoordinate>();

            foreach (var item in fenceMongoEntity.CoordinateList)
            {
                Map2DCoordinate  map  = new Map2DCoordinate();
                LocateInfo info;
                switch (gpsMapType)
                {
                    case GpsMapType.GDMAP:
                        info = gCJ02_WGS84_TransTools.gcj02_To_Wgs84(item.lat, item.lng);
                        map.lat = info.Latitude;
                        map.lng = info.longitude;
                        break;
                    case GpsMapType.BAIDUMAP:
                        info = gCJ02_WGS84_TransTools.bd09_To_Gps84(item.lat, item.lng);
                        map.lat = info.Latitude;
                        map.lng = info.longitude;
                        break;
                    default:
                        map.lat = item.lat;
                        map.lng = item.lng;
                        break;
                }
                CoordinateList.Add(map);
            }
            fenceMongoEntity.CoordinateList = CoordinateList;
            mongoDBCommand.InsertDocumentAsync(fenceMongoEntity).GetAwaiter().GetResult();
            return fenceMongoEntity;
        }

        public FenceMongoEntity Update(FenceMongoEntity fenceMongoEntity, GpsMapType gpsMapType)
        {

            List<Map2DCoordinate> CoordinateList = new List<Map2DCoordinate>();
            foreach (var item in fenceMongoEntity.CoordinateList)
            {
                Map2DCoordinate map = new Map2DCoordinate();
                LocateInfo info;
                switch (gpsMapType)
                {
                    case GpsMapType.GDMAP:
                        info = gCJ02_WGS84_TransTools.gcj02_To_Wgs84(item.lat, item.lng);
                        map.lat = info.Latitude;
                        map.lng = info.longitude;
                        break;
                    case GpsMapType.BAIDUMAP:
                        info = gCJ02_WGS84_TransTools.bd09_To_Gps84(item.lat, item.lng);
                        map.lat = info.Latitude;
                        map.lng = info.longitude;
                        break;
                    default:
                        map.lat = item.lat;
                        map.lng = item.lng;
                        break;
                }
                CoordinateList.Add(map);
            }
            fenceMongoEntity.CoordinateList = CoordinateList;


            var update = Builders<FenceMongoEntity>.Update
                .Set(s => s.FenceName, fenceMongoEntity.FenceName)
                .Set(s => s.FenceNumber, fenceMongoEntity.FenceNumber)
                .Set(s => s.CtrlCompanyId, fenceMongoEntity.CtrlCompanyId)
                .Set(s => s.CtrlCompanyName, fenceMongoEntity.CtrlCompanyName)
                .Set(s => s.WorkCompanyId, fenceMongoEntity.WorkCompanyId)
                .Set(s => s.WorkCompanyName, fenceMongoEntity.WorkCompanyName)
                .Set(s => s.ProvinceCode, fenceMongoEntity.ProvinceCode)
                .Set(s => s.ProvinceName, fenceMongoEntity.ProvinceName)
                .Set(s => s.CityCode, fenceMongoEntity.CityCode)
                .Set(s => s.CityName, fenceMongoEntity.CityName)
                .Set(s => s.CountyCode, fenceMongoEntity.CountyCode)
                .Set(s => s.CountyName, fenceMongoEntity.CountyName)
                .Set(s => s.EditorId, fenceMongoEntity.EditorId)
                .Set(s => s.Editor, fenceMongoEntity.Editor)
                .Set(s => s.EditTime, fenceMongoEntity.EditTime)
                .Set(s => s.IsEnable, fenceMongoEntity.IsEnable)
                .Set(s => s.FenceAlarmType, fenceMongoEntity.FenceAlarmType)
                .Set(s => s.Remark, fenceMongoEntity.Remark)
                .Set(s=>s.CoordinateList,fenceMongoEntity.CoordinateList)
                .Set(s => s.Polygon, fenceMongoEntity.Polygon);

            mongoDBCommand.UpdateDocumentAsync(s => s.Id == fenceMongoEntity.Id, update).GetAwaiter().GetResult();
            return mongoDBCommand.SelectDocumentAsync(s => s.Id == fenceMongoEntity.Id).GetAwaiter().GetResult();

        }

        public bool Delete(string id)
        {
           return  mongoDBCommand.DeleteDocumentAsync(s =>s.Id == id).GetAwaiter().GetResult().DeletedCount>0;
        }


        /// <summary>
        /// 返回目标点所在围栏列表
        /// </summary>
        /// <param name="lng"></param>
        /// <param name="lat"></param>
        /// <param name="gpsMapType"></param>
        /// <returns></returns>
        public List<FenceMongoEntity> GetIntoFenceList(double lng, double lat, string ProvinceCode, string CityCode, string CountyCode, GpsMapType gpsMapType)
        {
            string InAlarmStr = string.Empty;
            double fLng=lng;
            double fLat = lat;

            LocateInfo info;
            switch (gpsMapType)
            {
                case GpsMapType.GDMAP:
                    info = gCJ02_WGS84_TransTools.gcj02_To_Wgs84(lat, lng);
                    fLat = info.Latitude;
                    fLng = info.longitude;
                    break;
                case GpsMapType.BAIDUMAP:
                    info = gCJ02_WGS84_TransTools.bd09_To_Gps84(lat,lng);
                    fLat = info.Latitude;
                    fLng = info.longitude;
                    break;
                default:
                    fLat = lat;
                    fLng = lng;
                    break;
            }


            List<string> wheres = new List<string>();

            wheres.Add($"IsEnable: true");

            if (string.IsNullOrWhiteSpace(ProvinceCode))
                wheres.Add($"ProvinceCode:{ProvinceCode}");
            if (string.IsNullOrWhiteSpace(CityCode))
                wheres.Add($"CityCode:{CityCode}");
            if (string.IsNullOrWhiteSpace(CountyCode))
                wheres.Add($"CountyCode:{CountyCode}");

            string str =  string.Join(" , ", wheres)  ;

            InAlarmStr = "{ "+str+",  Polygon: { $geoIntersects: { $geometry: { type : \"Point\", coordinates : [" + fLng + "," + fLat + "] }}}} ";

            return mongoDBCommand.SelectDocumentsAsync(InAlarmStr).GetAwaiter().GetResult();
        }

        /// <summary>
        /// 返回 指定的目标点是否在指定的围栏内,如果在返回围栏 ,否则返回空
        /// </summary>
        /// <param name="id"></param>
        /// <param name="lng"></param>
        /// <param name="lat"></param>
        /// <param name="gpsMapType"></param>
        /// <returns></returns>
        public FenceMongoEntity IntoFence( string id ,double lng, double lat,GpsMapType gpsMapType)
        {  
            double fLng = lng;
            double fLat = lat;

            LocateInfo info;
            switch (gpsMapType)
            {
                case GpsMapType.GDMAP:
                    info = gCJ02_WGS84_TransTools.gcj02_To_Wgs84(lat, lng);
                    fLat = info.Latitude;
                    fLng = info.longitude;
                    break;
                case GpsMapType.BAIDUMAP:
                    info = gCJ02_WGS84_TransTools.bd09_To_Gps84(lat, lng);
                    fLat = info.Latitude;
                    fLng = info.longitude;
                    break;
            }
             
            string str = string.Empty;
             
            str = "{_id:\"" + id + "\", IsEnable: true,Polygon: { $geoIntersects: { $geometry: { type : \"Point\", coordinates : [" + lng + "," + lat + "] }}}} ";
 
            return  mongoDBCommand.SelectDocumentAsync(str).GetAwaiter().GetResult();
 
        }
    }
}